/*! \file tower.h
    \brief Tous ce qui concerne les tours.
    \author Angéline Guignard & Adrien Megueddem
    \copyright Imac Tour Defense
    \language C
    \updated 2013-05-19
*/

#ifndef _ITD__TOWER_H___
#define _ITD__TOWER_H___


#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "../include/modules/coordinates.h"
#include "../lib/GM/include/list.h"
#include "../include/modules/monster.h"
#include "../include/modules/sprite.h"

/*! \enum TypeTower tower.h "include/modules/tower.h"
 *  \brief Enum d'une type de tour
*/
typedef enum typetower{
	AUCUN,         /*!< AUCUN aucun type selectionné */
	ROCKET,        /*!< ROCKET type Rocket */
    HYBRID,        /*!< HYBRID type Hybride */
	LASER,         /*!< LASER type Laser */
	MACHINEGUN     /*!< MACHINEGUN type MachineGun */
}TypeTower;

/*! \struct MonsterDistance tower.h "include/modules/tower.h"
 *  \brief Struct correspondance entre une distance et le monstre concerné
*/
typedef struct monsterDistance{
    Monster *monster;       /*!< Monster *monster adresse du monstre */
    float distanceMtoT;     /*!< float distanceMtoT distance en OpenGL */
}MonsterDistance;

/*! \struct Tower tower.h "include/modules/tower.h"
 *  \brief Structure d'une tour
*/
typedef struct tower{
	GLuint *texture;		/*!< GLuint *texture texture de la tour */
	TypeTower type;			/*!< TypeTower type type Enum de la tour */
	float width;			/*!< float width taille en OpenGL de la largeur de la tour */
    float height;			/*!< float height taille en OpenGL de la hauteur de la tour */
	CoordOpenGL coord;		/*!< CoordOpenGL coord coordonnées en OpenGL de la tour */
    int lvl;                /*!< int lvl level de la tour */
	int damage;				/*!< int damage puissance de la tour */
	int rangePx;			/*!< int rangePx portée de la tour en pixel */
    float rangeGL;          /*!< float rangeGL portée de la tour en OpenGL */
	int cadence;			/*!< int cadence cadence de tir de la tour */
	int price;				/*!< int price prix de la tour */
    int priceUpgrade;       /*!< int priceUpgrade prix de l'upgrade */
	int isSet;				/*!< int isSet position finale de la tour (BOOL) */
    MonsterDistance target; /*!< MonsterDistance target adresse du monstre prit pour cible */
    int timerShoot;         /*!< int timerShoot timer qui permet de respecter la cadence de tir par nombre de tour de jeu */
    int select;             /*!< int select tour selectionnée (BOOL) */
    Sprite sprite;          /*!< Sprite sprite sprite de la tour */
}Tower;

/*! \fn createTower()
    \brief Permet de créer un tour
    \result on renvoit l'adresse de la tour créée
*/
Tower* createTower();

/*! \fn Tower* initTower(TypeTower type, GLuint *textureTower, unsigned int WINDOW_WIDTH, unsigned int WINDOW_HEIGHT, int squareSize)
    \brief initialise une tour déjà créée auparavant
    \param type type(ENUM) de la tour
    \param texture de la tour correspondant a son type
    \param WINDOW_WIDTH sert a la convertion SDLToOpenGL
    \param WINDOW_HEIGHT sert a la convertion SDLToOpenGL
    \result on renvoit l'adresse de la tour modifiée
*/
Tower* initTower(TypeTower type, GLuint *textureTower, unsigned int WINDOW_WIDTH, unsigned int WINDOW_HEIGHT, int squareSize);

/*! \fn List addTower(List listTower, TypeTower type, GLuint *textureTower, unsigned int WINDOW_WIDTH, unsigned int WINDOW_HEIGHT, int squareSize, CoordOpenGL mouseGL)
    \brief ajoute une tour a la liste de tour
    \param listTower liste sur laquele on rajoute la tour
    \param type type(ENUM) de la tour
    \param textureTower texture de la tour correspondant a son type
    \param WINDOW_WIDTH sert a la convertion SDLToOpenGL
    \param WINDOW_HEIGHT sert a la convertion SDLToOpenGL
    \param mouseGL coordonnées sur lesquelles on placera la tour
    \result on renvoit l'adresse de la list de tours modifiée
*/
List addTower(List listTower, TypeTower type, GLuint *textureTower, unsigned int WINDOW_WIDTH, unsigned int WINDOW_HEIGHT, int squareSize, CoordOpenGL mouseGL);

/*! \fn int getTowerType(Tower *t)
    \brief obtient le type de la tour selectionnée
    \param t adresse de la tour
    \result on renvoit le type (ENUM) de la tour
*/
int getTowerType(Tower *t);

/*! \fn void positionTower(Tower *t ,CoordOpenGL coord)
    \brief modifie la position de la tour selectionnée
    \param t adresse de la tour
    \param coord coordonnées sur lesquelles on placera la tour
    \result la tour a changée de position
*/
void positionTower(Tower *t ,CoordOpenGL coord);

/*! \fn List buyTower(Player *player, List listTower, TypeTower type, GLuint *textureTower, unsigned int WINDOW_WIDTH, unsigned int WINDOW_HEIGHT, int squareSize, CoordOpenGL mouseGL)
    \brief Permet d'acheter une tours.
    \param player
    \param listTower
    \param type
    \param textureTower
    \param WINDOW_WIDTH
    \param WINDOW_HEIGHT
    \param squareSize
    \param mouseGL
    \result Achète une tour.
*/
List buyTower(Player *player, List listTower, TypeTower type, GLuint *textureTower, unsigned int WINDOW_WIDTH, unsigned int WINDOW_HEIGHT, int squareSize, CoordOpenGL mouseGL);

/*! \fn void drawTower(Tower *t)
    \brief dessine une tour
    \param t adresse de la tour
    \result la tour est dessinée
*/
void drawTower(Tower *t);

/*! \fn void drawRange(Tower *t)
    \brief dessine la portée de la tour
    \param t adresse de la tour
    \result la portée est dessinée
*/
void drawRange(Tower *t);

/*! \fn float distanceTowerMonster(Tower *tower, Monster *monster)
    \brief calcul une distance entre une tour et un monstre
    \param t adresse de la tour
    \param monster adresse du monstre
    \result calcul une distance OpenGL
    \return la distance calculée en float
*/
float distanceTowerMonster(Tower *tower, Monster *monster);

/*! \fn float min(MonsterDistance tab[], int lenghtTab)
    \brief trouver le minimum dans un tableau de type MonsterDistance
    \param tab tableau de structure comprenant un Monster *m et une float distance
    \param lenghtTab taille du tableau passé en parametre
    \result trouve le minimum parmis toutes les distances du tableau
    \return la distance minimum en float
*/
float min(MonsterDistance tab[], int lenghtTab);

/*! \fn void updateTarget(Tower *tower, List listMonster)
    \brief changer la target d'une tour si besoin
    \param tower adresse de la tour
    \param listMonster liste des monstres
    \result change la target parmis la liste si la target a besoin d'etre mise a jour
*/
void updateTarget(Tower *tower, List listMonster);

/*! \fn int shootMonster(Tower *tower)
    \brief tire sur le monstre selectionné
    \param tower adresse de la tour
    \result on renvoit 1 si le monstre est mort, 0 sinon.
*/
int shootMonster(Tower *tower);

/*! \fn void updateTowerLevel(Tower *t, unsigned int WINDOW_WIDTH)
    \brief upgrade la tour selectionnée
    \param tower adresse de la tour
    \param WINDOW_WIDTH taille de la fenetre (largeur) utilisée pour convertir du SDL en OpenGL
    \result upgrade les caracteristiques d'une tour ainsi que son sprite, son coût
*/
void updateTowerLevel(Tower *t, unsigned int WINDOW_WIDTH);

/*! \fn List deleteTower(Tower *t, List *listTower)
    \brief supprimer une tour parmis une liste de tours
    \param tower adresse de la tour à supprimer
    \param listTower liste des tours à parcourir et à modifier
    \result supprime une tour de la liste
    \return la liste modifiée
*/
List deleteTower(Tower *t, List *listTower);

#endif